package com.ygxsk.carhome.utils;

import android.annotation.SuppressLint;
import android.content.Context;
import android.os.Build;

import androidx.annotation.RequiresApi;

import com.blankj.utilcode.util.LogUtils;
import com.blankj.utilcode.util.TimeUtils;
import com.ygxsk.carhome.constant.ConstantSign;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.Month;
import java.time.Period;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.HashMap;
import java.util.Map;

public class TimeUtilSer {

    //一个不是普通的时间，只有日期的
    public static final String simplemore = "yyyy-MM-dd";

    /**
     * 完整时间 yyyy-MM-dd HH:mm:ss
     */
    public static final String simple = "yyyy-MM-dd HH:mm:ss";

    /**
     * 第二种格式，是提交设备保养的时候 貌似只能使用这种斜杠的格式
     */
    public static final String simplePass = "yyyy/MM/dd HH:mm:ss";

    /**
     * 2020-7-6 09:11:24的时候添加了毫秒值，因为如果仅仅到【秒】级别的话，拍照太快，导致命名重复
     */
    public static final String simplePic = "yyyy_MM_dd_HH_mm_ss_SSS";

    /**
     * 获取当前时间
     *
     * @return
     */
    public static long getTime() {
        return System.currentTimeMillis() / 1000;
    }

    /**
     * 获取当前时间戳
     *
     * @return
     */
    public static long getTimeStamp() {
        return System.currentTimeMillis();
    }


    /**
     * 获取当前时间对应的字符串
     *
     * @return
     */
    public static String getTimeString(Long time) {
        Date date = new Date(time * 1000);
        DateFormat df = new SimpleDateFormat(simple);
        return df.format(date);
    }

	/*public static String getTimeStringPass(){
		return format(date, simple);
	}*/

    /**
     * 格式化时间，pattern 为 yyyy-MM-dd HH:mm:ss
     *
     * @param date data类型的时间
     * @return java.lang.String 返回 yyyy-MM-dd HH:mm:ss 类型字符串时间 <br/>
     * 如果data为null则返回null
     * @Author sunsong
     * @createDate 2019/11/6 11:07
     */
    public static String format(Date date) {
        return format(date, simple);
    }

    //该项目之中使用的 短日期格式的时间；
    public static String formatSelectTime(Date date) {
        return format(date, simplemore);
    }

    /**
     * 关于图片格式的修改内容
     */
    public static String formatPic(Date date) {
        return format(date, simplePic);
    }

    /**
     * 提交设备保养的格式
     */
    public static String formatPass(Date date) {
        return format(date, simplePass);
    }

    /**
     * 格式化时间
     *
     * @param date    data类型的时间
     * @param pattern pattern格式
     * @return java.lang.String 返回对应pattern 格式的字符串时间 <br/>
     * 如果data为null则返回null
     * @Author sunsong
     * @createDate 2019/11/6 11:08
     */
    public static String format(Date date, String pattern) {
        if (date != null) {
            SimpleDateFormat df = new SimpleDateFormat(pattern);
            return df.format(date);
        }
        return null;
    }

    /**
     * 获取字符串形式的当前时间
     *
     * @return java.lang.String 返回 yyyy-MM-dd HH:mm:ss 类型字符串时间
     * @Author sunsong
     * @createDate 2019/11/6 11:12
     */
    public static String getNow() {
        return format(new Date());
    }

    /**
     * 这种是专门为提交设备保养设计的格式
     */
    public static String getNowPass() {

        return formatPass(new Date());

    }

    /**
     * 获取图片的格式地址内容
     */
    public static String getNowPic() {
        return formatPic(new Date());
    }

    /**
     * 获取今天开始和结束
     *
     * @return
     */
    public static Map<String, Date> getTodayBeginAndEnd() {
        Calendar c1 = new GregorianCalendar();
        c1.set(Calendar.HOUR_OF_DAY, 0);
        c1.set(Calendar.MINUTE, 0);
        c1.set(Calendar.SECOND, 0);
        Calendar c2 = new GregorianCalendar();
        c2.set(Calendar.HOUR_OF_DAY, 23);
        c2.set(Calendar.MINUTE, 59);
        c2.set(Calendar.SECOND, 59);
        Map<String, Date> map = new HashMap<String, Date>();
        map.put("beginTime", c1.getTime());
        map.put("endTime", c2.getTime());
        return map;
    }

    /**
     * 获取今天开始时间
     *
     * @return
     */
    public static Date getTodayBegin() {
        Calendar c1 = new GregorianCalendar();
        c1.set(Calendar.HOUR_OF_DAY, 0);
        c1.set(Calendar.MINUTE, 0);
        c1.set(Calendar.SECOND, 0);
        return c1.getTime();
    }

    /**
     * 获取今天结束时间
     *
     * @return
     */
    public static Date getTodayEnd() {
        Calendar c2 = new GregorianCalendar();
        c2.set(Calendar.HOUR_OF_DAY, 23);
        c2.set(Calendar.MINUTE, 59);
        c2.set(Calendar.SECOND, 59);
        return c2.getTime();
    }

    /**
     * 获取date的第二天
     *
     * @return
     */
    public static Date getDayEnd(Date date) {
        Calendar c2 = Calendar.getInstance();
        c2.setTime(date);
        c2.set(Calendar.HOUR_OF_DAY, 23);
        c2.set(Calendar.MINUTE, 59);
        c2.set(Calendar.SECOND, 59);
        return c2.getTime();
    }


    /**
     * 获取今天 0.0.0秒的时间戳
     *
     * @return
     */
    public static long getTodayBeginTime() {
        Calendar c1 = new GregorianCalendar();
        c1.set(Calendar.HOUR_OF_DAY, 0);
        c1.set(Calendar.MINUTE, 0);
        c1.set(Calendar.SECOND, 0);
        return c1.getTimeInMillis() / 1000;
    }

    /**
     * 获取今天 23.59.59秒的时间戳
     *
     * @return
     */
    public static long getTodayEndTime() {
        Calendar c2 = new GregorianCalendar();
        c2.set(Calendar.HOUR_OF_DAY, 23);
        c2.set(Calendar.MINUTE, 59);
        c2.set(Calendar.SECOND, 59);
        return c2.getTimeInMillis() / 1000;
    }

    /**
     * 获取当前时间前一天字符串:yyyy-MM-dd
     *
     * @param date
     * @return
     */
    public static String getBeforeDate(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.DAY_OF_MONTH, -1);
        Date beforeDate = calendar.getTime();
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
        return simpleDateFormat.format(beforeDate);
    }

    /**
     * 获取当前时间前 N 天字符串:yyyy-MM-dd
     *
     * @param date
     * @return
     */
    public static String getBeforeNDate(Date date, int n) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.DAY_OF_MONTH, n);
        Date beforeDate = calendar.getTime();
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        return simpleDateFormat.format(beforeDate);
    }

    /**
     * 获取date后 N 天字符串:yyyy-MM-dd
     *
     * @param date
     * @return
     */
    public static Date getLastNDate(Date date, int n) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.DATE, n);
        return calendar.getTime();
    }

    /**
     * 字符串yyyy-MM-dd HH:mm:ss转换date类型
     *
     * @param dateStr
     * @return
     * @throws ParseException
     */
    public static Date formatDateStr(String dateStr) throws ParseException {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat(simple);
        return simpleDateFormat.parse(dateStr);
    }

    /**
     * 当月第一天
     *
     * @return
     */
    public static Date getFirstDayOfMonth() throws ParseException {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.DAY_OF_MONTH, calendar.getActualMinimum(Calendar.DAY_OF_MONTH));
        String date = simpleDateFormat.format(calendar.getTime());
        return simpleDateFormat.parse(date);

    }

    /**
     * 下月第一天
     *
     * @return
     */
    public static Date getFirstDayOfNextMonth() throws ParseException {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
        Calendar calendar = Calendar.getInstance();
        calendar.add(Calendar.MONTH, 1);
        calendar.set(Calendar.DAY_OF_MONTH, calendar.getActualMinimum(Calendar.DAY_OF_MONTH));
        String date = simpleDateFormat.format(calendar.getTime());
        return simpleDateFormat.parse(date);
    }

    /**
     * date下月第一天
     *
     * @return
     */
    public static Date getFirstOfNextMonth(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.MONTH, 1);
        calendar.set(Calendar.DAY_OF_MONTH, calendar.getActualMinimum(Calendar.DAY_OF_MONTH));
        return calendar.getTime();
    }

    /**
     * 获得本周一0点时间
     *
     * @return
     */
    @SuppressLint("WrongConstant")
    public static Date getTimesWeekmorning() {
        Calendar cal = Calendar.getInstance();
        cal.set(cal.get(Calendar.YEAR), cal.get(Calendar.MONDAY), cal.get(Calendar.DAY_OF_MONTH), 0, 0, 0);
        cal.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
        return cal.getTime();
    }

    /**
     * 获得周一0点时间
     *
     * @return
     */
    @SuppressLint("WrongConstant")
    public static Date getWeekFirst(Date date) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        cal.set(cal.get(Calendar.YEAR), cal.get(Calendar.MONDAY), cal.get(Calendar.DAY_OF_MONTH), 0, 0, 0);
        cal.set(Calendar.DAY_OF_WEEK, Calendar.SUNDAY);
        return cal.getTime();
    }

    /**
     * 获得本周日24点时间
     *
     * @return
     */
    public static Date getTimesWeeknight() {
        Calendar cal = Calendar.getInstance();
        cal.setTime(getTimesWeekmorning());
        cal.add(Calendar.DAY_OF_WEEK, 7);
        return cal.getTime();
    }

    /**
     * 获得周日24点时间
     *
     * @return
     */
    public static Date getWeekLast(Date date) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        cal.setTime(getWeekFirst(date));
        cal.add(Calendar.DAY_OF_WEEK, 7);
        return cal.getTime();
    }

    /**
     * 获取周一、下周一
     *
     * @return
     */
    public static Map<String, Date> getWeekDate(Date date) {
        Map<String, Date> map = new HashMap<>();
        //SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");

        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        cal.setFirstDayOfWeek(Calendar.MONDAY);// 设置一个星期的第一天，按中国的习惯一个星期的第一天是星期一
        int dayWeek = cal.get(Calendar.DAY_OF_WEEK);// 获得当前日期是一个星期的第几天
        if (dayWeek == 1) {
            dayWeek = 8;
        }
        //System.out.println("要计算日期为:" + sdf.format(cal.getTime())); // 输出要计算日期

        cal.add(Calendar.DATE, cal.getFirstDayOfWeek() - dayWeek);// 根据日历的规则，给当前日期减去星期几与一个星期第一天的差值
        Date mondayDate = cal.getTime();
        //System.out.println("所在周星期一的日期：" + weekBegin);


        cal.add(Calendar.DATE, 5 + cal.getFirstDayOfWeek());
        Date sundayDate = cal.getTime();
        //System.out.println("所在下周星期一的日期：" + weekEnd);

        map.put("mondayDate", mondayDate);
        map.put("sundayDate", sundayDate);

        return map;
    }

    /**
     * 时间+月+天
     *
     * @param date
     * @param monthCount
     * @param dayCount
     * @return
     */
    public static Date computeDateIncrease(Date date, Integer monthCount, Integer dayCount) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.MONTH, monthCount);//增加月
        calendar.add(Calendar.DAY_OF_MONTH, dayCount);//增加天
        return calendar.getTime();
    }

    /**
     * 时间+分钟
     *
     * @param date
     * @param minuteCount
     * @return
     */
    public static Date computeMinuteIncrease(Date date, Integer minuteCount) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.MINUTE, minuteCount);//增加
        return calendar.getTime();
    }

    /**
     * 获取两个时间差
     *
     * @param older      前一个时间
     * @param newer      后一个时间
     * @param chronoUnit 计算单位
     * @return long 相差的单位数量
     * @Author sunsong
     * @createDate 2019/12/13 9:25
     */
    @RequiresApi(api = Build.VERSION_CODES.O)
    public static long getTimeDifferent(Date older, Date newer, ChronoUnit chronoUnit) {
        LocalDateTime oldTime = LocalDateTime.ofInstant(older.toInstant(), ZoneId.systemDefault());
        LocalDateTime newTime = LocalDateTime.ofInstant(newer.toInstant(), ZoneId.systemDefault());
        return chronoUnit.between(oldTime, newTime);
    }

    /**
     * 获取两个时间差
     *
     * @param older      前一个时间
     * @param newer      后一个时间
     * @param chronoUnit 计算单位
     * @return long 相差的单位数量
     * @Author sunsong
     * @createDate 2019/12/13 9:25
     */
    @RequiresApi(api = Build.VERSION_CODES.O)
    public static long getTimeDifferent(String older, String newer, ChronoUnit chronoUnit) {
        DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        LocalDateTime oldTime = LocalDateTime.parse(older, df);
        LocalDateTime newTime = LocalDateTime.parse(newer, df);
        return chronoUnit.between(oldTime, newTime);
    }


    //获取时间差的内容

    /**
     * 使用Calendar对象计算时间差，可以按照需求定制自己的计算逻辑
     *
     * @param strDate
     * @throws ParseException
     */
    public static void calculateTimeDifferenceByCalendar(String strDate) throws ParseException {

        SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
        Date date = formatter.parse(strDate);

        Calendar c1 = Calendar.getInstance();   //当前日期
        Calendar c2 = Calendar.getInstance();
        c2.setTime(date);   //设置为另一个时间

        int year = c1.get(Calendar.YEAR);
        int oldYear = c2.get(Calendar.YEAR);

        //这里只是简单的对两个年份数字进行相减，而没有考虑月份的情况
        System.out.println("传入的日期与今年的年份差为：" + (year - oldYear));
    }


//    原文链接：https://blog.csdn.net/weixin_47385625/article/details/116602896

    /**
     * 使用java 8的Period的对象计算两个LocalDate对象的时间差，严格按照年、月、日计算，如：2018-03-12 与 2014-05-23 相差 3 年 9 个月 17 天
     *
     * @param year
     * @param month
     * @param dayOfMonth
     */
    public static void calculateTimeDifferenceByPeriod(int year, Month month, int dayOfMonth) {
        LocalDate today = null;
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            today = LocalDate.now();
        }
        System.out.println("Today：" + today);
        LocalDate oldDate = null;
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            oldDate = LocalDate.of(year, month, dayOfMonth);
        }
        System.out.println("OldDate：" + oldDate);

        Period p = null;
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            p = Period.between(oldDate, today);
        }

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            System.out.printf("目标日期距离今天的时间差：%d 年 %d 个月 %d 天\n", p.getYears(), p.getMonths(), p.getDays());
        }
    }

//    public static String dayComparePrecise(String startDate, String endDate) {
//        Date parse = null;
//        Date toDate = null;
//        try {
//            parse = new SimpleDateFormat("yyyy-MM-dd").parse(startDate);
//            toDate = new SimpleDateFormat("yyyy-MM-dd").parse(endDate);
//        } catch (ParseException e) {
//            e.printStackTrace();
//        }
//
//        Calendar from = Calendar.getInstance();
//        from.setTime(parse);
//        Calendar to = Calendar.getInstance();
//        to.setTime(toDate);
//
//        int fromYear = from.get(Calendar.YEAR);
//        int fromMonth = from.get(Calendar.MONTH);
//        int fromDay = from.get(Calendar.DAY_OF_MONTH);
//
//        int toYear = to.get(Calendar.YEAR);
//        int toMonth = to.get(Calendar.MONTH);
//        int toDay = to.get(Calendar.DAY_OF_MONTH);
//
//        int year = toYear - fromYear;
//        int month = toMonth - fromMonth;
//        int day = toDay - fromDay;
//
//        String result = year + "#" + month + "#" + day;
//        LogUtils.d(ConstantSign.LOGCAT_NOMAL+"result-->"+result);
//
////        JSONObject jsonObject = new JSONObject();
////        jsonObject.put("year",year);
////        jsonObject.put("month",month);
////        jsonObject.put("day",day);
//
//        return result;
//    }

    /**
     * 计算2个日期之间相差的  相差多少年月日
     * 比如：2011-02-02 到  2017-03-02 相差 6年，1个月，0天
     *
     * @param fromDate
     * @param toDate
     * @return
     */
    public static DayCompare dayComparePrecise(Context context, Date fromDate, Date toDate) {

        DayCompare dayCompare = null;

        try {
            //do

            Calendar from = Calendar.getInstance();
            from.setTime(fromDate);
            Calendar to = Calendar.getInstance();
            to.setTime(toDate);

            int fromYear = from.get(Calendar.YEAR);
            int fromMonth = from.get(Calendar.MONTH);
            int fromDay = from.get(Calendar.DAY_OF_MONTH);

            int toYear = to.get(Calendar.YEAR);
            int toMonth = to.get(Calendar.MONTH);
            int toDay = to.get(Calendar.DAY_OF_MONTH);

            int year = toYear - fromYear;
            int month = toMonth - fromMonth;
            int day = toDay - fromDay;

            //以上会出现月份的负数 DayCompare{year=7, month=-6, day=7} 有问题；
            if (month < 0) {
                month = 12 - from.get(Calendar.MONTH) + to.get(Calendar.MONTH);
                year = year - 1;
            }

            if (day < 0) {
                day = from.getActualMaximum(Calendar.DAY_OF_MONTH) - from.get(Calendar.DAY_OF_MONTH) + to.get(Calendar.DAY_OF_MONTH);
                month = month - 1;
            }

            DayCompare dayCompareResult = new DayCompare(year, month, day);

            dayCompare = dayCompareResult;

//            LogUtils.d(ConstantSign.LOGCAT_NOMAL + "---fromDate-->" + TimeUtils.date2String(fromDate));
//            LogUtils.d(ConstantSign.LOGCAT_NOMAL + "---toDate-->" + TimeUtils.date2String(toDate));
//            LogUtils.d(ConstantSign.LOGCAT_NOMAL + "---dayCompare-统共的计算的->" + dayCompare);
            //DayCompare{year=7, month=-6, day=7}
            //单独的计算的结果；
            //itchen-->---dayCompare-统共的计算的->DayCompare{year=6, month=1, day=0}
            //itchen-->---dayCompare-->DayCompare{year=6, month=73, day=2220}

        } catch (Exception e) {

            //catch
            if (e != null) {
                CommUtils.addLogTryCatch(context, "dayComparePrecise", e.getMessage());
                LogUtils.d(ConstantSign.LOGCAT_NOMAL + "--比较日期的报错是-->" + e.getLocalizedMessage());
            }

            e.printStackTrace();
        }

        return dayCompare;
    }

    /**
     * //单独计算的
     * 计算2个日期之间相差的  以年、月、日为单位，各自计算结果是多少
     * 比如：2011-02-02 到  2017-03-02
     * 以年为单位相差为：6年
     * 以月为单位相差为：73个月
     * 以日为单位相差为：2220天
     *
     * @param fromDate
     * @param toDate
     * @return
     */
    public static DayCompare dayCompare(Date fromDate, Date toDate) {
        Calendar from = Calendar.getInstance();
        from.setTime(fromDate);
        Calendar to = Calendar.getInstance();
        to.setTime(toDate);
        //只要年月
        int fromYear = from.get(Calendar.YEAR);
        int fromMonth = from.get(Calendar.MONTH);

        int toYear = to.get(Calendar.YEAR);
        int toMonth = to.get(Calendar.MONTH);

        int year = toYear - fromYear;
        int month = toYear * 12 + toMonth - (fromYear * 12 + fromMonth);
        int day = (int) ((to.getTimeInMillis() - from.getTimeInMillis()) / (24 * 3600 * 1000));

        DayCompare dayCompare = new DayCompare(year, month, day);

//        LogUtils.d(ConstantSign.LOGCAT_NOMAL + "---dayCompare-->" + dayCompare);
        //itchen-->---dayCompare-->DayCompare{year=6, month=73, day=2220}

        return dayCompare;

        //return DayCompare.builder().day(day).month(month).year(year).build();
    }

    //默认的获取今年的数据
    public static String getYearNow() {

        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy");
        String dateYearFirst = TimeUtils.getNowString(simpleDateFormat);

        //默认是【年月日】的填充，默认是当前的年；
        //String dateYearFirst = TimeUtils.getNowString();
        //year_upLoad = dateYearFirst;
        //datasDateYear.add(dateYearFirst+"年");
        //datasDateYear.add(getString(R.string.choosesingleyear));

        return dateYearFirst;
    }

    /**
     * 某个日期date增加count个自然月
     *
     * @param date  某个日期(yyyy-MM-dd格式)
     * @param count 相加的月数
     * @return
     * @throws ParseException
     */
    public static String addMonth(String date, int count) throws ParseException {

        //SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        SimpleDateFormat sdf = new SimpleDateFormat(simplemore);

        int year = Integer.parseInt(date.split("-")[0]);
        int month = Integer.parseInt(date.split("-")[1]);
        int day = Integer.parseInt(date.split("-")[2]);
        int addY = count / 12;
        int addM = count % 12;
        if (addM + month > 12) {
            year = year + addY + 1;
            month = (month + addM) % 12;
        } else {
            year += addY;
            month += addM;
        }
        if (day >= 28) {
            if (day >= getDayByMonth(year + "-" + Integer.parseInt(date.split("-")[1]))) {  //为月底或大于月底
                day = getDayByMonth(year + "-" + month);  //日期变为对应月月底
            }
        }

        return sdf.format(sdf.parse(year + "-" + month + "-" + day));
    }

    /**
     * 获取当前月份的天数
     *
     * @param date
     * @return
     */
    public static int getDayByMonth(String date) {
        int year = Integer.parseInt(date.split("-")[0]);
        int month = Integer.parseInt(date.split("-")[1]);
        int days[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
        if (2 == month && 0 == (year % 4) && (0 != (year % 100) || 0 == (year % 400))) {
            days[1] = 29;
        }
        return Integer.valueOf(days[month - 1]);
    }

    @RequiresApi(api = Build.VERSION_CODES.O)
    public static void main(String[] args) {

        //这里是测试内容
//        long timeDifferent = getTimeDifferent("2019-11-30 21:00:01", "2019-12-01 08:00:00", ChronoUnit.HOURS);
        //System.out.println("itchen-->时间差"+timeDifferent);

        //System.err.println(getTime());
    }
}

